package com.wondertek.poms.core.manager;

import cn.hutool.core.collection.CollectionUtil;
import com.wondertek.poms.common.constant.Constants;
import com.wondertek.poms.core.filter.RuleFilterChain;
import com.wondertek.poms.core.filter.impl.*;
import com.wondertek.poms.core.service.IPcPrdInfoRuleService;
import com.wondertek.poms.core.service.IPrdRuleSecondClassifyService;
import com.wondertek.poms.dao.po.Content;
import com.wondertek.poms.dao.po.PrdInfo;
import com.wondertek.poms.dao.po.PrdInfoRule;
import com.wondertek.poms.dao.po.PrdRuleSecondClassify;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.*;

@Slf4j
@Component
public class PrdInfoRuleManager {

    @Autowired
    private IPcPrdInfoRuleService prdInfoRuleService;

    /**
     * <p><b>Title:</b> getWhichPrdInfo</p>
     * <p><b>Description:</b> 获取符合哪个商品包，条件有： 包限制条件、包已选条件</p>
     *
     * @param c
     * @param prdInfo
     * @return  true表示通过商品包规则
     */
    public Boolean getWhichPrdInfo(Content c, PrdInfo prdInfo) {
        log.info("手动入包流程|媒资ID:" + c.getAssetId() + "|内容:" + c.getContentId() + "|商品包限制条件、包已选条件 判断开始");

        Long prdInfoId = prdInfo.getPrdInfoId();

        Map<Integer, List<PrdInfoRule>> pirMap = getPrdInfoRuleMap(prdInfoId);
        List<PrdInfoRule> limitPrdInfoRules = pirMap.get(Constants.RULE_TYPE_4);
        if (CollectionUtil.isNotEmpty(limitPrdInfoRules)) {
            log.info("主流程|媒资ID:" + c.getAssetId() + "|内容:" + c.getContentId() + "|商品包:" + prdInfoId + "|限制规则数量:" + limitPrdInfoRules.size());
            if (isMatchPrdInfoLimitRule(c, limitPrdInfoRules)){
                return false;
            }
        }

        List<PrdInfoRule> selectPrdInfoRules = pirMap.get(Constants.RULE_TYPE_2);
        if (selectPrdInfoRules == null){
            return true;
        }
        log.info("手动入包流程|媒资ID:" + c.getAssetId() + "|内容:" + c.getContentId() + "|商品包:" + prdInfoId + "|已选规则数量:" + selectPrdInfoRules.size());
        return isMatchPrdInfoSelectRule(c, selectPrdInfoRules);
    }

    /**
     * <p><b>Title:</b> getPrdInfoRuleMap</p>
     * <p><b>Description:</b> 根据商品包id查询商品包规则，并且按照限制和已选进行分类</p>
     *
     * @param prdInfoId
     * @return
     * @author douzi
     */
    public Map<Integer, List<PrdInfoRule>> getPrdInfoRuleMap(Long prdInfoId) {
        Map<Integer, List<PrdInfoRule>> map = new HashMap<>();
        List<PrdInfoRule> pirs = prdInfoRuleService.findAllByPrdInfoId(prdInfoId);

        pirs.forEach(r -> {
            List<PrdInfoRule> partPirs = null;
            if (!map.containsKey(r.getIsprdSel())) {
                partPirs = new ArrayList<>();
            } else {
                partPirs = map.get(r.getIsprdSel());
            }

            partPirs.add(r);
            map.put(r.getIsprdSel(), partPirs);
        });

        return map;
    }

    /**
     * <p><b>Title:</b> isMatchPrdInfoLimitRule</p>
     * <p><b>Description:</b> 是否匹配商品包限制规则</p>
     *
     * @param vo
     * @param limitPrdInfoRules
     * @return
     * @author douzi
     */
    public boolean isMatchPrdInfoLimitRule(Content c, List<PrdInfoRule> limitPrdInfoRules) {
        boolean isMatch = false;

        for (PrdInfoRule limitRule : limitPrdInfoRules) {
            isMatch = contentFilter(limitRule, c, true);
            if (isMatch)
                break;
        }
        return isMatch;
    }

    /**
     * <p><b>Title:</b> isMatchPrdInfoSelectRule</p>
     * <p><b>Description:</b> 是否匹配商品包已选规则</p>
     *
     * @param vo
     * @param selectPrdInfoRules
     * @return
     * @author douzi
     */
    public boolean isMatchPrdInfoSelectRule(Content c, List<PrdInfoRule> selectPrdInfoRules) {
        boolean isMatch = false;

        for (PrdInfoRule selectRule : selectPrdInfoRules) {
            isMatch = contentFilter(selectRule, c, false);
            if (isMatch)
                break;
        }
        return isMatch;
    }

    @Autowired
    private IPrdRuleSecondClassifyService prdRuleSecondClassifyService;

    /**
     * <p><b>Title:</b> contentFilter</p>
     * <p><b>Description:</b> 商品包规则过滤</p>
     *
     * @param rule    商品包规则
     * @param vo      接收的内容vo
     * @param isLimit 是否是限制规则
     * @return
     * @author douzi
     */
    public boolean contentFilter(PrdInfoRule rule, Content c, boolean isLimit) {
        setSecondClassifys(rule);

        RuleFilterChain rfc = new RuleFilterChain();
        if (isLimit) {
            rfc.addFilter(new CopyRightBlackAreaFilter());	//版权地域范围 黑名单
        } else {
            rfc.addFilter(new CopyRightWhiteAreaFilter())	//版权地域范围 白名单
                    .addFilter(new MediaUsageCodeFilter());		//码率
        }
        rfc.addFilter(new CopyRightCpIdFilter())    		//版权所属CP
                .addFilter(new AssistFilter())				//辅助分类
                .addFilter(new OutputFilter())				//是否输出
                .addFilter(new ContentTypeFilter())			//内容类别
                .addFilter(new FreeTypeFilter())			//资费类型
                .addFilter(new CopyRightOptimalFilter())	//版权最优
                .addFilter(new FirClassifyFilter())			//内容一级分类
                .addFilter(new CopyRightTypeFilter())		//版权类型
                .addFilter(new CopyRightTerminalFilter())	//版权终端
                .addFilter(new HasVideoFilter())			//是否可无媒体文件
                .addFilter(new CopyRightScopeFilter())		//版权授权范围
                .addFilter(new FormTypeFilter())          	//剧集类型
                .addFilter(new NeedDRMFilter())				//数字版权保护
                .addFilter(new AssertLevelFilter())			//内容评级
                .addFilter(new RecommendationFilter())		//推荐标签
                .addFilter(new CopyRightScopeFilter())		//版权授权范围
                .addFilter(new AuthorizationWayFilter())	//授权方式
                .addFilter(new SecondClassifyFilter())		//二级分类
                .doFilter( rule, c, rfc);

        if (rfc.isFlag()) {
            log.info("商品包规则|内容id:" + c.getContentId() + "assetId:" + c.getAssetId() + "|商品包ID:" + rule.getPrdInfoId() + "|" + (isLimit ? "商品包限制规则" : "商品包已选规则") + "|匹配成功|copyRightObjectID:" + c.getCopyrightObjectId() + "|" + rule.toString());
        } else {
            log.info("商品包规则|内容id:" + c.getContentId() + "assetId:" + c.getAssetId() + "|商品包ID:" + rule.getPrdInfoId() + "|" + (isLimit ? "商品包限制规则" : "商品包已选规则") + "|匹配失败|copyRightObjectID:" + c.getCopyrightObjectId() + "|" + rfc.getResultStr().toString());
        }
        return rfc.isFlag();
    }

    /**
     * <p><b>Title:</b> setSecondClassifys</p>
     * <p><b>Description:</b> 设置二级分类列表值进规则对象 </p>
     * @author douzi
     * @param rule
     */
    private void setSecondClassifys(PrdInfoRule rule) {
        PrdRuleSecondClassify params = new PrdRuleSecondClassify();
        params.setPrdRuleId(rule.getPrdRuleId());
        List<PrdRuleSecondClassify> dbprsc = prdRuleSecondClassifyService.findAll(params);
        Set<PrdRuleSecondClassify> set = new HashSet<>(dbprsc);
        rule.setSecondClassifys(set);
    }
}
